package co.edu.usbcali.correspondencia.modelo.control;

import co.edu.usbcali.correspondencia.dataaccess.daoFactory.XMLHibernateDaoFactory;
import co.edu.usbcali.correspondencia.dataaccess.sessionFactory.HibernateSessionFactory;
import co.edu.usbcali.correspondencia.exceptions.*;
import co.edu.usbcali.correspondencia.modelo.*;
import co.edu.usbcali.correspondencia.utilities.Utilities;

import java.math.BigDecimal;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;

/**
 * interface UnidadResidencialLogic
 * 
 * @author Zathura Code Generator http://code.google.com/p/zathura
 * 
 */
public class UnidadResidencialLogic implements IUnidadResidencialLogic {
	public List<UnidadResidencial> getUnidadResidencial() throws Exception {
		List<UnidadResidencial> list = new ArrayList<UnidadResidencial>();

		try {
			list = XMLHibernateDaoFactory.getInstance()
					.getUnidadResidencialDAO().findAll();
		} catch (Exception e) {
			throw new ZMessManager().new GettingException(ZMessManager.ALL
					+ "UnidadResidencial");
		} finally {
		}

		return list;
	}

	public void saveUnidadResidencial(String unrBarrio, String unrDireccion,
			String unrNit, String unrNombre, String unrTelefono,
			String admCodigo_Administrador, String ciuCodigo_Ciudad,
			String estCodigo_Estado) throws Exception {
		UnidadResidencial entity = null;

		try {
			
			if (unrNit == null || unrNit.equals(" ")) {
				throw new ZMessManager().new EmptyFieldException("Nit");
			}

			if ((unrNit != null)
					&& (Utilities.checkWordAndCheckWithlength(unrNit, 10) == false)) {
				throw new ZMessManager().new NotValidFormatException("Nit");
			}
			
			if (admCodigo_Administrador == null || admCodigo_Administrador.equals(" ")) {
				throw new ZMessManager().new EmptyFieldException(
						"Codigo Administrador");
			}

			if ((admCodigo_Administrador != null)
					&& (Utilities.checkWordAndCheckWithlength(
							admCodigo_Administrador, 10) == false)) {
				throw new ZMessManager().new NotValidFormatException(
						"Codigo Administrador");
			}
			
			if (unrNombre == null || unrNombre.equals(" ")) {
				throw new ZMessManager().new EmptyFieldException("Nombre");
			}

			if ((unrNombre != null)
					&& (Utilities.checkWordAndCheckWithlength(unrNombre, 50) == false)) {
				throw new ZMessManager().new NotValidFormatException(
						"Nombre");
			}
			
			if (unrTelefono == null || unrTelefono.equals(" ")) {
				throw new ZMessManager().new EmptyFieldException("Telefono");
			}

			if ((unrTelefono != null)
					&& (Utilities.checkWordAndCheckWithlength(unrTelefono, 20) == false)) {
				throw new ZMessManager().new NotValidFormatException(
						"Telefono");
			}
			
			if (unrDireccion == null || unrDireccion.equals(" ")) {
				throw new ZMessManager().new EmptyFieldException("Direccion");
			}

			if ((unrDireccion != null)
					&& (Utilities.checkWordAndCheckWithlength(unrDireccion, 30) == false)) {
				throw new ZMessManager().new NotValidFormatException(
						"Direccion");
			}
			
			if (unrBarrio == null || unrBarrio.equals(" ")) {
				throw new ZMessManager().new EmptyFieldException("Barrio");
			}

			if ((unrBarrio != null)
					&& (Utilities.checkWordAndCheckWithlength(unrBarrio, 30) == false)) {
				throw new ZMessManager().new NotValidFormatException(
						"Barrio");
			}

			if (ciuCodigo_Ciudad == null || ciuCodigo_Ciudad.equals(" ")) {
				throw new ZMessManager().new EmptyFieldException(
						"Codigo Ciudad");
			}
			
			if (ciuCodigo_Ciudad.equals("-1")) {
				throw new Exception("Por Favor Seleccione Una Ciudad");
			}

			if ((ciuCodigo_Ciudad != null)
					&& (Utilities.checkWordAndCheckWithlength(ciuCodigo_Ciudad,
							10) == false)) {
				throw new ZMessManager().new NotValidFormatException(
						"Codigo Ciudad");
			}

			if (estCodigo_Estado == null || estCodigo_Estado.equals(" ")) {
				throw new ZMessManager().new EmptyFieldException(
						"Estado");
			}

			if ((estCodigo_Estado != null)
					&& (Utilities.checkWordAndCheckWithlength(estCodigo_Estado,
							10) == false)) {
				throw new ZMessManager().new NotValidFormatException(
						"Estado");
			}

			IAdministradorLogic logicAdministrador1 = new AdministradorLogic();
			ICiudadLogic logicCiudad2 = new CiudadLogic();
			IEstadoLogic logicEstado3 = new EstadoLogic();
			Administrador administradorClass = logicAdministrador1
					.getAdministrador(admCodigo_Administrador);
			Ciudad ciudadClass = logicCiudad2.getCiudad(ciuCodigo_Ciudad);
			Estado estadoClass = logicEstado3.getEstado(estCodigo_Estado);

			if (administradorClass == null) {
				throw new ZMessManager().new ForeignException("administrador");
			}

			if (ciudadClass == null) {
				throw new ZMessManager().new ForeignException("ciudad");
			}

			if (estadoClass == null) {
				throw new ZMessManager().new ForeignException("estado");
			}

			entity = getUnidadResidencial(unrNit);

			if (entity != null) {
				throw new ZMessManager(ZMessManager.ENTITY_WITHSAMEKEY);
			}

			entity = new UnidadResidencial();
			entity.setUnrBarrio(unrBarrio);
			entity.setUnrDireccion(unrDireccion);
			entity.setUnrNit(unrNit);
			entity.setUnrNombre(unrNombre);
			entity.setUnrTelefono(unrTelefono);
			entity.setAdministrador(administradorClass);
			entity.setCiudad(ciudadClass);
			entity.setEstado(estadoClass);
			HibernateSessionFactory.beginTransaction();
			XMLHibernateDaoFactory.getInstance().getUnidadResidencialDAO()
					.save(entity);
			HibernateSessionFactory.commit();
		} catch (Exception e) {
			HibernateSessionFactory.rollback();
			throw e;
		} finally {
			HibernateSessionFactory.closeSession();
		}
	}

	public void deleteUnidadResidencial(String unrNit) throws Exception {
		UnidadResidencial entity = null;

		if (unrNit == null) {
			throw new ZMessManager().new EmptyFieldException("Nit");
		}

		List<Division> divisions = null;
		List<Presupuesto> presupuestos = null;
		List<ZonaComun> zonaComuns = null;
		entity = getUnidadResidencial(unrNit);

		if (entity == null) {
			throw new ZMessManager().new EmptyFieldException(
					"UnidadResidencial");
		}

		try {
			divisions = XMLHibernateDaoFactory.getInstance().getDivisionDAO()
					.findByProperty("unidadResidencial.unrNit", unrNit);

			if (Utilities.validationsList(divisions) == true) {
				throw new ZMessManager().new DeletingException("divisions");
			}

			presupuestos = XMLHibernateDaoFactory.getInstance()
					.getPresupuestoDAO().findByProperty(
							"unidadResidencial.unrNit", unrNit);

			if (Utilities.validationsList(presupuestos) == true) {
				throw new ZMessManager().new DeletingException("presupuestos");
			}

			zonaComuns = XMLHibernateDaoFactory.getInstance().getZonaComunDAO()
					.findByProperty("unidadResidencial.unrNit", unrNit);

			if (Utilities.validationsList(zonaComuns) == true) {
				throw new ZMessManager().new DeletingException("zonaComuns");
			}

			HibernateSessionFactory.beginTransaction();
			XMLHibernateDaoFactory.getInstance().getUnidadResidencialDAO()
					.delete(entity);
			HibernateSessionFactory.commit();
		} catch (Exception e) {
			HibernateSessionFactory.rollback();
			throw e;
		} finally {
			HibernateSessionFactory.closeSession();
		}
	}

	public void updateUnidadResidencial(String unrBarrio, String unrDireccion,
			String unrNit, String unrNombre, String unrTelefono,
			String admCodigo_Administrador, String ciuCodigo_Ciudad,
			String estCodigo_Estado) throws Exception {
		UnidadResidencial entity = null;

		try {
			if (unrNit == null || unrNit.equals(" ")) {
				throw new ZMessManager().new EmptyFieldException("Nit");
			}

			if ((unrNit != null)
					&& (Utilities.checkWordAndCheckWithlength(unrNit, 10) == false)) {
				throw new ZMessManager().new NotValidFormatException("Nit");
			}
			
			if (admCodigo_Administrador == null || admCodigo_Administrador.equals(" ")) {
				throw new ZMessManager().new EmptyFieldException(
						"Codigo Administrador");
			}

			if ((admCodigo_Administrador != null)
					&& (Utilities.checkWordAndCheckWithlength(
							admCodigo_Administrador, 10) == false)) {
				throw new ZMessManager().new NotValidFormatException(
						"Codigo Administrador");
			}
			
			if (unrNombre == null || unrNombre.equals(" ")) {
				throw new ZMessManager().new EmptyFieldException("Nombre");
			}

			if ((unrNombre != null)
					&& (Utilities.checkWordAndCheckWithlength(unrNombre, 50) == false)) {
				throw new ZMessManager().new NotValidFormatException(
						"Nombre");
			}
			
			if (unrTelefono == null || unrTelefono.equals(" ")) {
				throw new ZMessManager().new EmptyFieldException("Telefono");
			}

			if ((unrTelefono != null)
					&& (Utilities.checkWordAndCheckWithlength(unrTelefono, 20) == false)) {
				throw new ZMessManager().new NotValidFormatException(
						"Telefono");
			}
			
			if (unrDireccion == null || unrDireccion.equals(" ")) {
				throw new ZMessManager().new EmptyFieldException("Direccion");
			}

			if ((unrDireccion != null)
					&& (Utilities.checkWordAndCheckWithlength(unrDireccion, 30) == false)) {
				throw new ZMessManager().new NotValidFormatException(
						"Direccion");
			}
			
			if (unrBarrio == null || unrBarrio.equals(" ")) {
				throw new ZMessManager().new EmptyFieldException("Barrio");
			}

			if ((unrBarrio != null)
					&& (Utilities.checkWordAndCheckWithlength(unrBarrio, 30) == false)) {
				throw new ZMessManager().new NotValidFormatException(
						"Barrio");
			}

			if (ciuCodigo_Ciudad == null || ciuCodigo_Ciudad.equals(" ")) {
				throw new ZMessManager().new EmptyFieldException(
						"Codigo Ciudad");
			}
			
			if (ciuCodigo_Ciudad.equals("-1")) {
				throw new Exception("Por Favor Seleccione Una Ciudad");
			}

			if ((ciuCodigo_Ciudad != null)
					&& (Utilities.checkWordAndCheckWithlength(ciuCodigo_Ciudad,
							10) == false)) {
				throw new ZMessManager().new NotValidFormatException(
						"Codigo Ciudad");
			}

			if (estCodigo_Estado == null || estCodigo_Estado.equals(" ")) {
				throw new ZMessManager().new EmptyFieldException(
						"Estado");
			}

			if ((estCodigo_Estado != null)
					&& (Utilities.checkWordAndCheckWithlength(estCodigo_Estado,
							10) == false)) {
				throw new ZMessManager().new NotValidFormatException(
						"Estado");
			}

			IAdministradorLogic logicAdministrador1 = new AdministradorLogic();

			ICiudadLogic logicCiudad2 = new CiudadLogic();

			IEstadoLogic logicEstado3 = new EstadoLogic();
			Administrador administradorClass = logicAdministrador1
					.getAdministrador(admCodigo_Administrador);
			Ciudad ciudadClass = logicCiudad2.getCiudad(ciuCodigo_Ciudad);
			Estado estadoClass = logicEstado3.getEstado(estCodigo_Estado);

			if (administradorClass == null) {
				throw new ZMessManager().new ForeignException("administrador");
			}

			if (ciudadClass == null) {
				throw new ZMessManager().new ForeignException("ciudad");
			}

			if (estadoClass == null) {
				throw new ZMessManager().new ForeignException("estado");
			}

			entity = getUnidadResidencial(unrNit);

			if (entity == null) {
				throw new ZMessManager(ZMessManager.ENTITY_NOENTITYTOUPDATE);
			}

			entity.setUnrBarrio(unrBarrio);
			entity.setUnrDireccion(unrDireccion);
			entity.setUnrNit(unrNit);
			entity.setUnrNombre(unrNombre);
			entity.setUnrTelefono(unrTelefono);
			entity.setAdministrador(administradorClass);
			entity.setCiudad(ciudadClass);
			entity.setEstado(estadoClass);
			HibernateSessionFactory.beginTransaction();
			XMLHibernateDaoFactory.getInstance().getUnidadResidencialDAO()
					.update(entity);
			HibernateSessionFactory.commit();
		} catch (Exception e) {
			HibernateSessionFactory.rollback();
			throw e;
		} finally {
			HibernateSessionFactory.closeSession();
		}
	}
	
	

	public UnidadResidencial getUnidadResidencial(String unrNit)
			throws Exception {
		UnidadResidencial entity = null;

		try {
			entity = XMLHibernateDaoFactory.getInstance()
					.getUnidadResidencialDAO().findById(unrNit);
		} catch (Exception e) {
			throw new ZMessManager().new FindingException("UnidadResidencial");
		} finally {
		}

		return entity;
	}

	public List<UnidadResidencial> findPageUnidadResidencial(
			String sortColumnName, boolean sortAscending, int startRow,
			int maxResults) throws Exception {
		List<UnidadResidencial> entity = null;

		try {
			entity = XMLHibernateDaoFactory.getInstance()
					.getUnidadResidencialDAO()
					.findPageUnidadResidencial(sortColumnName, sortAscending,
							startRow, maxResults);
		} catch (Exception e) {
			throw new ZMessManager().new FindingException("UnidadResidencial");
		} finally {
		}

		return entity;
	}

	public Long findTotalNumberUnidadResidencial() throws Exception {
		Long entity = null;

		try {
			entity = XMLHibernateDaoFactory.getInstance()
					.getUnidadResidencialDAO()
					.findTotalNumberUnidadResidencial();
		} catch (Exception e) {
			throw new ZMessManager().new FindingException(
					"UnidadResidencial Count");
		} finally {
		}

		return entity;
	}

	/**
	 * 
	 * @param varibles
	 *            este arreglo debera tener:
	 * 
	 *            [0] = String variable = (String) varibles[i]; representa como
	 *            se llama la variable en el pojo
	 * 
	 *            [1] = Boolean booVariable = (Boolean) varibles[i + 1];
	 *            representa si el valor necesita o no ''(comillas simples)usado
	 *            para campos de tipo string
	 * 
	 *            [2] = Object value = varibles[i + 2]; representa el valor que
	 *            se va a buscar en la BD
	 * 
	 *            [3] = String comparator = (String) varibles[i + 3]; representa
	 *            que tipo de busqueda voy a hacer.., ejemplo: where
	 *            nombre=william o where nombre<>william, en este campo iria el
	 *            tipo de comparador que quiero si es = o <>
	 * 
	 *            Se itera de 4 en 4..., entonces 4 registros del arreglo
	 *            representan 1 busqueda en un campo, si se ponen mas pues el
	 *            continuara buscando en lo que se le ingresen en los otros 4
	 * 
	 * 
	 * @param variablesBetween
	 * 
	 *            la diferencia son estas dos posiciones
	 * 
	 *            [0] = String variable = (String) varibles[j]; la variable ne
	 *            la BD que va a ser buscada en un rango
	 * 
	 *            [1] = Object value = varibles[j + 1]; valor 1 para buscar en
	 *            un rango
	 * 
	 *            [2] = Object value2 = varibles[j + 2]; valor 2 para buscar en
	 *            un rango ejempolo: a > 1 and a < 5 --> 1 seria value y 5 seria
	 *            value2
	 * 
	 *            [3] = String comparator1 = (String) varibles[j + 3];
	 *            comparador 1 ejemplo: a comparator1 1 and a < 5
	 * 
	 *            [4] = String comparator2 = (String) varibles[j + 4];
	 *            comparador 2 ejemplo: a comparador1>1 and a comparador2<5 (el
	 *            original: a > 1 and a < 5) *
	 * @param variablesBetweenDates
	 *            (en este caso solo para mysql) [0] = String variable =
	 *            (String) varibles[k]; el nombre de la variable que hace
	 *            referencia a una fecha
	 * 
	 *            [1] = Object object1 = varibles[k + 2]; fecha 1 a
	 *            comparar(deben ser dates)
	 * 
	 *            [2] = Object object2 = varibles[k + 3]; fecha 2 a
	 *            comparar(deben ser dates)
	 * 
	 *            esto hace un between entre las dos fechas.
	 * 
	 * @return lista con los objetos que se necesiten
	 * @throws Exception
	 */
	public List<UnidadResidencial> findByCriteria(Object[] variables,
			Object[] variablesBetween, Object[] variablesBetweenDates)
			throws Exception {
		List<UnidadResidencial> list = new ArrayList<UnidadResidencial>();
		String where = new String();
		String tempWhere = new String();

		if (variables != null) {
			for (int i = 0; i < variables.length; i++) {
				if ((variables[i] != null) && (variables[i + 1] != null)
						&& (variables[i + 2] != null)
						&& (variables[i + 3] != null)) {
					String variable = (String) variables[i];
					Boolean booVariable = (Boolean) variables[i + 1];
					Object value = variables[i + 2];
					String comparator = (String) variables[i + 3];

					if (booVariable.booleanValue()) {
						tempWhere = (tempWhere.length() == 0) ? ("(model."
								+ variable + " " + comparator + " \'" + value + "\' )")
								: (tempWhere + " AND (model." + variable + " "
										+ comparator + " \'" + value + "\' )");
					} else {
						tempWhere = (tempWhere.length() == 0) ? ("(model."
								+ variable + " " + comparator + " " + value + " )")
								: (tempWhere + " AND (model." + variable + " "
										+ comparator + " " + value + " )");
					}
				}

				i = i + 3;
			}
		}

		if (variablesBetween != null) {
			for (int j = 0; j < variablesBetween.length; j++) {
				if ((variablesBetween[j] != null)
						&& (variablesBetween[j + 1] != null)
						&& (variablesBetween[j + 2] != null)
						&& (variablesBetween[j + 3] != null)
						&& (variablesBetween[j + 4] != null)) {
					String variable = (String) variablesBetween[j];
					Object value = variablesBetween[j + 1];
					Object value2 = variablesBetween[j + 2];
					String comparator1 = (String) variablesBetween[j + 3];
					String comparator2 = (String) variablesBetween[j + 4];
					tempWhere = (tempWhere.length() == 0) ? ("(" + value + " "
							+ comparator1 + " " + variable + " and " + variable
							+ " " + comparator2 + " " + value2 + " )")
							: (tempWhere + " AND (" + value + " " + comparator1
									+ " " + variable + " and " + variable + " "
									+ comparator2 + " " + value2 + " )");
				}

				j = j + 4;
			}
		}

		if (variablesBetweenDates != null) {
			for (int k = 0; k < variablesBetweenDates.length; k++) {
				if ((variablesBetweenDates[k] != null)
						&& (variablesBetweenDates[k + 1] != null)
						&& (variablesBetweenDates[k + 2] != null)) {
					String variable = (String) variablesBetweenDates[k];
					Object object1 = variablesBetweenDates[k + 1];
					Object object2 = variablesBetweenDates[k + 2];
					String value = null;
					String value2 = null;

					try {
						Date date1 = (Date) object1;
						Date date2 = (Date) object2;
						value = Utilities
								.formatDateWithoutTimeInAStringForBetweenWhere(date1);
						value2 = Utilities
								.formatDateWithoutTimeInAStringForBetweenWhere(date2);
					} catch (Exception e) {
						list = null;
						throw e;
					}

					tempWhere = (tempWhere.length() == 0) ? ("(model."
							+ variable + " between \'" + value + "\' and \'"
							+ value2 + "\')") : (tempWhere + " AND (model."
							+ variable + " between \'" + value + "\' and \'"
							+ value2 + "\')");
				}

				k = k + 2;
			}
		}

		if (tempWhere.length() == 0) {
			where = null;
		} else {
			where = "(" + tempWhere + ")";
		}

		try {
			list = XMLHibernateDaoFactory.getInstance()
					.getUnidadResidencialDAO().findByCriteria(where);
		} catch (Exception e) {
			throw new Exception(e.getMessage());
		} finally {
		}

		return list;
	}

	// metodo que consulta y llena el data talbe de unidad residencial....
	public List<UnidadResidencial> llenarDataTableUnRes(String nombConsulta)
			throws Exception {
		List<UnidadResidencial> lista = new ArrayList<UnidadResidencial>();
		try {

			lista = XMLHibernateDaoFactory.getInstance()
					.getUnidadResidencialDAO().llenarDataTableUnRes(
							nombConsulta);
		} catch (Exception e) {
			throw new Exception(e.getMessage());
		} finally {
		}
		return lista;
	}
	
	// metodo que consulta y llena el data talbe de unidad residencial....
	public List<UnidadResidencial> llenarDataTableUnRes2(String nit)
			throws Exception {
		List<UnidadResidencial> lista = new ArrayList<UnidadResidencial>();
		try {

			lista = XMLHibernateDaoFactory.getInstance()
					.getUnidadResidencialDAO().llenarDataTableUnRes2(
							nit);
		} catch (Exception e) {
			throw new Exception(e.getMessage());
		} finally {
		}
		return lista;
	}
	

	// Consulta LLena DataTable por Nombre
	public List<UnidadResidencial> llenarTblNombUnRe(String nombUnid, String codAdmin)
			throws Exception {
		List<UnidadResidencial> lista = new ArrayList<UnidadResidencial>();
		try {
			
			if ((nombUnid != null)
					&& (Utilities.checkWordAndCheckWithlength(nombUnid, 50) == false)) {
				throw new ZMessManager().new NotValidFormatException(
						"Nombre Consulta");
			}
			
			if (nombUnid == null || nombUnid.equals("")) {
				throw new ZMessManager().new EmptyFieldException(
						"Nombre Consulta");
			}

			lista = XMLHibernateDaoFactory.getInstance()
					.getUnidadResidencialDAO().llenarTblNombUnRe(nombUnid, codAdmin);
		} catch (Exception e) {
			throw new Exception(e.getMessage());
		} finally {
		}
		return lista;
	}
	
	// Consulta LLena DataTable por NIT
	public List<UnidadResidencial> llenarTblNITUnRe(String nit, String codAdmin)
			throws Exception {
		List<UnidadResidencial> lista = new ArrayList<UnidadResidencial>();
		try {

			lista = XMLHibernateDaoFactory.getInstance()
					.getUnidadResidencialDAO().llenarTblNITUnRe(nit, codAdmin);
		} catch (Exception e) {
			throw new Exception(e.getMessage());
		} finally {
		}
		return lista;
	}

}
